public class SortingHelper {

    private SortingHelper() {}

    public static <E extends Comparable<E>> void swap(E[] data, int i, int j) {
        E temp = data[i];
        data[i] = data[j];
        data[j] = temp;
    }
    public static <E extends Comparable<E>> boolean isSorted(E[] data) {
        for (int i = 1; i < data.length - 1; i++)
            if (data[i - 1].compareTo(data[i]) > 0)
                return false;
        return true;
    }

    public static <E extends Comparable<E>> void test(Type sortType, E[] data) {

        long startTime = System.nanoTime();
        switch (sortType) {
            case SELECTION -> SelectionSort.sort(data);
            case INSERTION_V1 -> InsertionSort.sort(data);
            case INSERTION_V2 -> InsertionSort.sortReverse(data);
            case INSERTION_V3 -> InsertionSort.sortV3(data);
            case BUBBLE -> BubbleSort.sort(data);
            case BUBBLE_V2 -> BubbleSort.sort2(data);
            case BUBBLE_V3 -> BubbleSort.sort3(data);
            case MERGE -> MergeSort.sort(data);
            case QUICK_V1 -> QuickSort.sortV1(data);
            case QUICK_V2 -> QuickSort.sortV2(data);
            case QUICK_V3 -> QuickSort.sortV3(data);
            case HEAP -> HeapSort.sort(data);
            case SHELL -> ShellSort.sort(data);
            case BULK -> BulkSort.sort(data);
            default -> throw new RuntimeException("unknown sort type");
        }
        long endTime = System.nanoTime();
        double costTime = (endTime - startTime) / 1000000000.0;
        System.out.printf(" > %s, 数据规模 = %d, 耗时 = %.9f秒\n",
                sortType, data.length, costTime);

        if (!isSorted(data))
            throw new RuntimeException("sort failed");
    }
}
